package smallfrench.moteur.biblio;

import java.awt.Color;

import smallfrench.moteur.biblio.err.ExceptionInterruption;
import smallfrench.moteur.interp.IEntreeConsole;
import smallfrench.moteur.interp.ISortieConsole;
import smallfrench.moteur.interp.ProcessusScript;
import smallfrench.moteur.interp.RObjet;
import smallfrench.moteur.interp.err.RException;

public class AConsole extends AObjet {

	public static final AClasse CLASSE = AClasse.creer(
			AConsole.class, "Console");

	private IEntreeConsole entree;

	private ISortieConsole sortie;


	@AnnotationMembre
	public AConsole() {
	}


	private void verifierEntreeSortie() {
		if (entree == null) {
			ProcessusScript ps = ProcessusScript.getInstance();
			if (ps == null) {
				throw new RuntimeException("Impossible de récupérer l’entrée "
						+ "et la sortie");
			}
			entree = ps.entree;
			sortie = ps.sortie;
		}
	}


	@AnnotationMembre(parametresVariables = true)
	public void ecrire(RObjet[] params) {

		verifierEntreeSortie();

		for (RObjet i : params) {
			String string = i == null ? "rien" : i.toString();
			sortie.ecrire(string);
		}
	}

	@AnnotationMembre(parametresVariables = true)
	public void ecrireLigne(RObjet[] params) {

		verifierEntreeSortie();

		for (RObjet i : params) {
			String string = i == null ? "rien" : i.toString();
			sortie.ecrire(string);
		}
		sortie.ecrireLigne();
	}

	/**
	 * Fonction blocante retournant un caractère lu sur l’entrée standard
	 * @return Le caractère lu
	 * @throws RException
	 */
	@AnnotationMembre
	public RChaine lireCaractere() throws RException {

		verifierEntreeSortie();

		try {
			return new RChaine(entree.lireCaractere());
		} catch (InterruptedException e) {
			throw ExceptionInterruption.nouvelleException();
		}
	}

	/**
	 * Fonction non blocante.
	 * @return Le numéro d’une des touches appuyées, ou -1 si aucune touche
	 * n’est appuyée.
	 */
	@AnnotationMembre
	public REntier lireTouche() {

		verifierEntreeSortie();

		return new REntier(entree.lireTouche());
	}

	/**
	 * @return vrai si des caractères sont en attente d’être lus.
	 */
	@AnnotationMembre
	public RBooleen caracteresDisponibles() {

		verifierEntreeSortie();

		return RBooleen.nouveau(entree.caracteresDisponibles());
	}

	/**
	 * Efface la console, réinitialise le curseur.
	 */
	@AnnotationMembre
	public void effacer() {

		verifierEntreeSortie();

		sortie.effacer();
	}

	/**
	 * Modifie la couleur de premier plan.
	 * @param params
	 */
	@AnnotationMembre(parametresVariables = true)
	public void modifierPremierPlan(RObjet[] params) {

		verifierEntreeSortie();

		if (params.length == 0)
			return;

		RObjet arg = params[0];

		if (arg instanceof REntier) {
			REntier couleur = (REntier)arg;
			sortie.setPremierPlan(new Color(couleur.getValeurInt()));
		} else if (arg instanceof RCouleur) {
			RCouleur couleur = (RCouleur)arg;
			sortie.setPremierPlan(couleur.valeur);
		}
	}

	/**
	 * 
	 * @param x
	 * @param y
	 */
	@AnnotationMembre
	public void modifierPositionCurseur(REntier x, REntier y) {

		verifierEntreeSortie();

		sortie.setPositionCurseur(x.getValeurInt(), y.getValeurInt());
	}

	@AnnotationMembre
	public REntier hauteur() {

		verifierEntreeSortie();

		return new REntier(sortie.getHauteur());
	}

	@AnnotationMembre
	public REntier largeur() {

		verifierEntreeSortie();

		return new REntier(sortie.getLargeur());
	}

	@AnnotationMembre
	@Override
	public RChaine enChaine() {
		return new RChaine("Console");
	}
}
